package com.mazaiting.auth.security.core.clientdetails;

import com.mazaiting.auth.enums.PasswordEncoderTypeEnum;
import com.mazaiting.common.core.domain.result.Result;
import com.mazaiting.manager.api.IOAuth2ClientFeignClient;
import com.mazaiting.manager.dto.SysOauthClientDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

/**
 * OAuth2 客户端信息
 */
@Slf4j
@Service("clientDetailsServiceImpl")
@RequiredArgsConstructor
public class ClientDetailsServiceImpl implements ClientDetailsService {

    private final IOAuth2ClientFeignClient oAuth2ClientFeignClient;

    @Override
    @Cacheable(cacheNames = "auth", key = "'oauth-client:'+#clientId")
    public ClientDetails loadClientByClientId(String clientId) {
        try {
            // 获取客户端信息
            Result<SysOauthClientDTO> oAuth2ClientDTOResult = oAuth2ClientFeignClient.getOAuth2ClientById(clientId);
            if (!ObjectUtils.isEmpty(oAuth2ClientDTOResult) && oAuth2ClientDTOResult.check()) {
                SysOauthClientDTO sysOAuthClientDTO = oAuth2ClientDTOResult.getData();
                BaseClientDetails clientDetails = new BaseClientDetails(
                        sysOAuthClientDTO.getClientId(),
                        sysOAuthClientDTO.getResourceIds(),
                        sysOAuthClientDTO.getScope(),
                        sysOAuthClientDTO.getAuthorizedGrantTypes(),
                        sysOAuthClientDTO.getAuthorities(),
                        sysOAuthClientDTO.getWebServerRedirectUri()
                );
                clientDetails.setClientSecret(PasswordEncoderTypeEnum.BCRYPT.getPrefix() + sysOAuthClientDTO.getClientSecret());
                clientDetails.setAccessTokenValiditySeconds(sysOAuthClientDTO.getAccessTokenValidity());
                clientDetails.setRefreshTokenValiditySeconds(sysOAuthClientDTO.getRefreshTokenValidity());
                return clientDetails;
            } else {
                throw new NoSuchClientException("No client with requested id: " + clientId);
            }
        } catch (Exception e) {
            log.error("查询客户端详情异常: " + e.getMessage());
            throw new NoSuchClientException("No client with requested id: " + clientId);
        }
    }
}
